--- richtext support

-- r"abc"
-- r.blue"highlight"
-- r{colour = "white", id = "H1", clickable = true}"https://cn.bing.com"

local r = Class(function(self, s)
	self.colour = nil
	self.clickable = false

	self.head = self
	self.next = nil
	self.prev = nil

	if type(s) == "table" then
		for k,v in pairs(s)do
			self[k] = v
		end
	elseif s ~= nil then
		self.string = tostring(s)
	end
	
end)

function r:__call(s)
	assert(self.string == nil)
	assert(s ~= nil)
	self.string = tostring(s)
end

function r:__concat(other)
	if type(other) == "string" or type(other) == "number" then
		return self:__concat(r(other))
	else
		self.next = other
		other.prev = self
		other.head = self.head
		return other
	end
end

function r:__tostring()
	return string.format("RichText - #%d, %s",
		#self, string.sub(self:PlainText(),1, 30))
end

function r:PlainText()
	local temp = {}
	local node = self.head
	while node ~= nil do
		table.insert(temp, node.string)
		node = node.next
	end
	return table.concat(temp, "")
end

function r:RichText()
	local result = {}
	local node = self.head
	local objectindex = 1
	while node ~= nil do
		for _,v in ipairs(node:ToArray()) do
			v.objectindex = objectindex
			table.insert(result, v)
		end
		node = node.next
		objectindex = objectindex + 1
	end
	return result
end

local tolist = require "rg_util.utf8".tolist

function r:ToArray()
	local result = {}
	if self.string ~= nil then
		for _,v in ipairs(tolist(self.string))do
			table.insert(result, {
				char = v, 
				object = self,
				colour = self.colour, 
				id = self.id,
				clickable = self.clickable,
			})
		end
	end
	return result
end

function r:__len()
	return string.len(self:PlainText())
end

function r:SetColour(c)
	self.colour = c
	return self
end

function r.white(...)
	return r{colour = "white"}(...)
end


return r